package com.aerors.Util;

public class GeoUtils {

	//Web墨卡托地球常数
	protected static double originShift = 2 * Math.PI * 6378137 / 2.0;
	
	/**
	 * 根据经度获取OSM切片规范下的行号
	 * 
	 * @param lon
	 * @param zoom
	 * @return
	 */
	public static int getOSMTileXFromLongitude(double lon, int zoom) {
		return (int) (Math.floor((lon + 180) / 360 * Math.pow(2, zoom)));
	}

	/**
	 * 根据纬度获取OSM切片规范下的列号
	 * 
	 * @param lat
	 * @param zoom
	 * @return
	 */
	public static int getOSMTileYFromLatitude(double lat, int zoom) {
		return (int) (Math
				.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) + 1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 2
						* Math.pow(2, zoom)));
	}
	
	
	public static double[] lonLat2WebMercator(double lon, double lat) {
		double[] mercator = new double[2];
		double x = lon * originShift / 180.0;
		double y = Math.log(Math.tan((90 + lat) * Math.PI / 360.0)) / (Math.PI / 180.0);
		y = y * originShift / 180;

		mercator[0] = x;
		mercator[1] = y;

		return mercator;
	}

	public static double[] WebMercator2lonLat(double x, double y) {
		double[] lonlat = new double[2];
		double lon = (x / originShift) * 180;
		double lat = (y / originShift) * 180;
		lat = 180 / Math.PI * (2 * Math.atan(Math.exp(lat * Math.PI / 180.0)) - Math.PI / 2.0);

		lonlat[0] = lon;
		lonlat[1] = lat;

		return lonlat;
	}
	
	/**
	 * 已知切片列号和缩放级别,求经度
	 * 
	 * @param x
	 * @param z
	 * @return
	 */
	public static double tile2lon(int x, int z) {
		return x / Math.pow(2.0, z) * 360.0 - 180;
	}

	/**
	 * 已知切片行号和缩放级别,求经度
	 * 
	 * @param y
	 * @param z
	 * @return
	 */
	public static double tile2lat(int y, int z) {
		double n = Math.PI - (2.0 * Math.PI * y) / Math.pow(2.0, z);
		return Math.toDegrees(Math.atan(Math.sinh(n)));
	}
}
